#include "rclcpp/rclcpp.hpp"
#include "nav_msg_pkg/srv/add_ints.hpp"

using nav_msg_pkg::srv::AddInts;

class AddIntsClient : public rclcpp::Node
{
public:
    AddIntsClient() : Node("add_ints_client")
    {
        RCLCPP_INFO(this->get_logger(), "add_ints_client 节点已经启动!");
        add_ints_client_ = this->create_client<AddInts>("add_ints");
    }
    // 连接服务器
    bool connect_server()
    {
        while (!add_ints_client_->wait_for_service(std::chrono::seconds(1)))
        {
            // 对 ctrl + c 退出程序
            if (!rclcpp::ok())
            {
                RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "退出！");
                return false;
            }
            RCLCPP_INFO(this->get_logger(), "等待服务器启动...");
        }
        return true;
    }
    // 发送请求
    rclcpp::Client<AddInts>::FutureAndRequestId send_request(int a, int b)
    {
        auto request = std::make_shared<AddInts::Request>();
        request->num1 = a;
        request->num2 = b;
        auto result_future = add_ints_client_->async_send_request(request);
        return result_future;
    }

private:
    rclcpp::Client<AddInts>::SharedPtr add_ints_client_;
};
// ros2 run node_pkg demo_srv_client 10 20
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Usage: add_ints_client X Y");
        return -1;
    }
    /* 初始化rclcpp  */
    rclcpp::init(argc, argv);
    /* 产生一个 节点 */
    auto client = std::make_shared<AddIntsClient>();
    // 判断连接服务器
    bool connect_flag = client->connect_server();
    if (!connect_flag)
    {
        RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "服务未启动!");
        return 0;
    }
    // 发送请求
    auto future = client->send_request(atoi(argv[1]), atoi(argv[2]));
    // 处理响应
    if (rclcpp::spin_until_future_complete(client, future) == rclcpp::FutureReturnCode::SUCCESS)
    {
        RCLCPP_INFO(client->get_logger(), "响应结果: %d", future.get()->sum);
    }
    else
    {
        RCLCPP_ERROR(client->get_logger(), "请求失败!");
    }
    /* 停止运行 */
    rclcpp::shutdown();
    return 0;
}